package com.ungs.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.ungs.dao.OrdenTrabajoDAO;
import com.ungs.entities.Material;
import com.ungs.entities.OrdenTrabajo;
import com.ungs.entities.ProcesoXOrden;
import com.ungs.utils.Constantes;

public class OrdenTrabajoDAOImpl extends EntidadDAOImpl<OrdenTrabajo> implements
		OrdenTrabajoDAO {

	@SuppressWarnings("unchecked")
	@Override
	public OrdenTrabajo getUltimaOrdenTrabajo() throws HibernateException {
		OrdenTrabajo ordenTrabajo = null;
		List<OrdenTrabajo> ordenTrabajoList = new ArrayList<OrdenTrabajo>();

		logger.info("Obteniendo ultima orden de trabajo");
		try {
			iniciaConexion();
			Criteria criteria = getSession().createCriteria(OrdenTrabajo.class);
			criteria.setMaxResults(1);
			criteria.add(Restrictions.eq("estadoLogico", "A"));
			criteria.addOrder(Order.desc("id"));

			ordenTrabajoList = (List<OrdenTrabajo>) criteria.list();

			if (ordenTrabajoList.size() > 0)
				ordenTrabajo = ordenTrabajoList.get(0);

		} catch (HibernateException he) {
			logger.error("Error al traer la ultima de orden trabajo: "
					+ OrdenTrabajo.class + "DAO");
			manejaExcepcion(he);
			throw he;
		} finally {
			getSession().close();
		}

		return ordenTrabajo;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<OrdenTrabajo> getOrdenTrabajoSinFinalizar()
			throws HibernateException {
		List<OrdenTrabajo> ordenTrabajoList = new ArrayList<OrdenTrabajo>();

		logger.info("Obteniendo las ordenes de trabajo sin finalizar");
		try {
			iniciaConexion();
			Criteria criteria = getSession().createCriteria(OrdenTrabajo.class);
			criteria.add(Restrictions.not(Restrictions.eq("estado",
					Constantes.ESTADO_FINALIZADO)));
			criteria.add(Restrictions.not(Restrictions.eq("estado",
					Constantes.ESTADO_FINALIZADO_SC)));

			ordenTrabajoList = (List<OrdenTrabajo>) criteria.list();

		} catch (HibernateException he) {
			logger.error("Error al traer las ordenes de trabajo sin finalizar: "
					+ OrdenTrabajo.class + "DAO");
			manejaExcepcion(he);
			throw he;
		} finally {
			getSession().close();
		}
		return ordenTrabajoList;
	}

	@Override
	public OrdenTrabajo getOrdenTrabajoByNumIdentificatorio(
			String numIdentificatorio) throws HibernateException {
		OrdenTrabajo ordenTrabajo = null;

		logger.info("Obteniendo la orden de trabajo por numero identificatorio");
		try {
			iniciaConexion();
			Criteria criteria = getSession().createCriteria(OrdenTrabajo.class);
			criteria.add(Restrictions.eq("numIdentificatorio",
					numIdentificatorio));

			ordenTrabajo = (OrdenTrabajo) criteria.uniqueResult();

		} catch (HibernateException he) {
			logger.error("Error al traer la orden de trabajo por numero identificatorio: "
					+ OrdenTrabajo.class + "DAO");
			manejaExcepcion(he);
			throw he;
		}
		return ordenTrabajo;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Material> getMaterialesByOrdenTrabajo(OrdenTrabajo ordenTrabajo)
			throws HibernateException {
		List<Material> materialList = new ArrayList<Material>();

		logger.info("Obteniendo los materiales por orden de trabajo");
		try {
			iniciaConexion();
			Criteria criteria = getSession().createCriteria(Material.class);
			Criteria critOT = criteria.createCriteria("ordenTrabajo");
			critOT.add(Restrictions.eq("id", ordenTrabajo.getId()));

			materialList = (List<Material>) criteria.list();

		} catch (HibernateException he) {
			logger.error("Error al traer los materiales de la OT: "
					+ OrdenTrabajo.class + "DAO");
			manejaExcepcion(he);
			throw he;
		} finally {
			getSession().close();
		}
		return materialList;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ProcesoXOrden> getProcesosXOrdenByOrdenTrabajo(
			OrdenTrabajo ordenTrabajo) throws HibernateException {
		List<ProcesoXOrden> procesoXOrdenList = new ArrayList<ProcesoXOrden>();

		logger.info("Obteniendo los procesos por orden de trabajo");
		try {
			iniciaConexion();
			Criteria criteria = getSession()
					.createCriteria(ProcesoXOrden.class);
			Criteria critOT = criteria.createCriteria("ordenTrabajo");
			critOT.add(Restrictions.eq("id", ordenTrabajo.getId()));

			procesoXOrdenList = (List<ProcesoXOrden>) criteria.list();

		} catch (HibernateException he) {
			logger.error("Error al traer los procesos de la OT: "
					+ OrdenTrabajo.class + "DAO");
			manejaExcepcion(he);
			throw he;
		} finally {
			getSession().close();
		}
		return procesoXOrdenList;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<OrdenTrabajo> getOrdenTrabajoUrgente()
			throws HibernateException {
		List<OrdenTrabajo> ordenTrabajoList = new ArrayList<OrdenTrabajo>();

		logger.info("Obteniendo las ordenes de trabajo urgentes");
		try {
			iniciaConexion();
			Criteria criteria = getSession().createCriteria(OrdenTrabajo.class);
			criteria.addOrder(Order.asc("fechaPrometida"));
			criteria.add(Restrictions.not(Restrictions.eq("estado",
					Constantes.ESTADO_FINALIZADO)));
			criteria.add(Restrictions.not(Restrictions.eq("estado",
					Constantes.ESTADO_FINALIZADO_SC)));

			ordenTrabajoList = (List<OrdenTrabajo>) criteria.list();

		} catch (HibernateException he) {
			logger.error("Error al traer las ordenes de trabajo por fecha: "
					+ OrdenTrabajo.class + "DAO");
			manejaExcepcion(he);
			throw he;
		}
		return ordenTrabajoList;
	}

}
